/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ua.yandex.collections;

/**
 *
 * @author Владислав
 */
public class MyArrayList implements MyList{

    Object[] nodeArray;
    int nodeCount;
    static final int DEFAULT_CAPACITY = 10;
    
    public MyArrayList() {
        this(DEFAULT_CAPACITY);
    }
    
    public MyArrayList(int initialCapacity) {
        nodeArray = new Object[initialCapacity];
    }
    
    public void ensureCapacity(int minCapacity) {
        int k = 1;
        while (nodeArray.length * k < minCapacity) {
            k *= 2;
        }
        Object[] tmp = new Object[nodeArray.length * k];
        System.arraycopy(nodeArray, 0, nodeArray, 0, nodeCount);
        nodeArray = tmp;
    }
    
    @Override
    public void add(Object e) {
        add(nodeCount, e);
    }//добавляет элемент в конец коллекции

    
    @Override
    public void add(int index, Object e) {
        addAll(index, new Object[]{ e });
    } //добавляет элемент в указанное место коллекции, и бросает исключение если индекс выходит за рамки

    @Override
    public void addAll(Object[] c) {
        addAll(nodeCount, c);
    } //добавляет массив элементов в конец коллекции

    @Override
    public void addAll(int index, Object[] c) {
        if (index < 0 || index > nodeCount) {
            throw new IndexOutOfBoundsException();
        }
        ensureCapacity(nodeCount + c.length);
        System.arraycopy(nodeArray, index, nodeArray, index + c.length, nodeCount - index);
        System.arraycopy(c, 0, nodeArray, index, c.length);
        nodeCount = nodeCount + c.length;
    } //добавляет массив элементов в указанное место коллекции, и бросает исключение если индекс выходит за рамки

    @Override
    public Object get(int index) {
        if (index < 0 || index >= nodeCount) {
            throw new IndexOutOfBoundsException();
        }
        return nodeArray[index];
    } //возвращает элемент по индексу, и бросает исключение если индекс выходит за рамки

    @Override
    public Object remove(int index) {
        if (index < 0 || index >= nodeCount) {
            throw new IndexOutOfBoundsException();
        }
        Object[] tmp = new Object[nodeArray.length - 1];
        System.arraycopy(nodeArray, 0, tmp, 0, index);
        System.arraycopy(nodeArray, index + 1, tmp, index, nodeCount - index - 1);
        Object res = get(index);
        nodeCount--;
        nodeArray = tmp;
        return res;
    }//удаляет элемент по индексу, и бросает исключение если индекс выходит за рамки

    @Override
    public void set(int index, Object e) {
        if (index < 0 || index >= nodeCount) {
            throw new IndexOutOfBoundsException();
        }
        nodeArray[index] = e;
    }//изменяет значение элемента, и бросает исключение если индекс выходит за рамки

    @Override
    public int indexOf(Object o) {
        for (int index = 0; index < nodeCount; index++) {
            if (nodeArray[index].equals(o)) {
                return index;
            }
        }
        return -1;
    } //поиск индекса по значению элемента (выводит индекс первого найденного, или -1 в случае его отсутствия)

    @Override
    public int size() {
        return nodeCount;
    }//размер коллекции

    @Override
    public void clear() {
        nodeCount = 0;
        nodeArray = new Object[DEFAULT_CAPACITY];
    }//удаляет содержимое коллекции

    @Override
    public boolean isEmpty() {
        return nodeCount == 0;
    } //возвращает true если в коллекции нет элементов

    @Override
    public Object[] toArray() {
        Object[] res = new Object[nodeCount];
        System.arraycopy(nodeArray, 0, res, 0, nodeCount);
        return res;
    }//преобразует коллекцию в массив объектов

    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        for (int index = 0; index < nodeCount; index++) {
            res.append(", ");
            res.append(nodeArray[index]);
        }
        if (nodeCount != 0) {
            res.delete(0, 2);
        }
        return res.toString();
    } //возвращает строку, в которой через запятую выводятся значения элементов в коллекции

}
